#ifndef _IM_SERVER_COMET_MESSAGE_OUTLET_ADAPTER_
#define _IM_SERVER_COMET_MESSAGE_OUTLET_ADAPTER_

#include "CometMessageOutletService.h"

#include "im/common/common.h"
#include "melon/client/thrift_client_pool.h"
// #include "melon/client/fixed_service_locator.h"
#include "melon/client/zk_service_locator.h"

namespace imserver {

using melon::client::ClientPool;

// 调用哪个comet_message_outlet_service由调用者（如message_service）决定，由参数server_key指定
class CometMessageOutletAdapter {
public:
  static CometMessageOutletAdapter & instance() {
    static CometMessageOutletAdapter adapter;
    return adapter;
  }

  int DistributeMessage(const std::string& server_key, const std::list<int64_t>& uids, const ImMessage & message,
      int max_retry = 1) {
    for(int i = 0; i < max_retry; ++i) {
      CometMessageOutletServiceClient * client = pool_.Alloc(server_key);
      if (client == NULL) {
        LOG_ERROR("CometMessageOutletAdapter::DistributeMessage --> connect err. sender:" << message.sender <<
            " server_key:" << server_key);
        return -1;
      }

      bool success = true;
      try {
        client->DistributeMessage(uids, message);
        LOG_INFO("CometMessageOutletAdapter::DistributeMessage --> ok. sender:" << message.sender << " receiver:"
              << message.receiver << " uid_size:" << uids.size() << " server_key:" << server_key << " retry:" << i);
      } catch (const std::exception & e) {
        LOG_ERROR("CometMessageOutletAdapter::DistributeMessage --> err. error:" << e.what() << " sender:" <<
            message.sender << " receiver:" << message.receiver << " uid_size:" << uids.size() << " server_key:" <<
            server_key << " retry:" << i);
        success = false;
      }
      pool_.Release(server_key, client, success);
      if (success) {
        return 0;
      }
    }
    return -2;
  }

private:
  CometMessageOutletAdapter() {
    ConfigReader cfg("../conf/rpc_adapters.conf");
    std::string default_location(cfg.Get("comet_message_outlet_service", "service_list"));
    pool_.set_default_location(default_location);
    // pool_.set_locator(new melon::client::FixedServiceLocator(location));
    ConfigReader zk_cfg("../conf/zookeeper.conf");
    if (!zk_cfg) {
      LOG_WARN("Config file ../conf/zookeeper.conf read error!");
      return;
    }
    pool_.set_locator(new melon::client::ZkServiceLocator(zk_cfg.Get("zookeeper", "service_registry").c_str()));
  }

  ClientPool<CometMessageOutletServiceClient> pool_;
};

}

#endif // _IM_SERVER_COMET_MESSAGE_OUTLET_ADAPTER_
